package com.example.exporttemplate.service;

import cn.hutool.poi.word.Word07Writer;
import com.aspose.words.DocumentBuilder;
import com.aspose.words.SaveFormat;
import com.example.exporttemplate.domain.TableContent;
import com.example.exporttemplate.utils.AsposeWordUtil;
import com.example.exporttemplate.utils.PictureUtils;
import com.example.exporttemplate.utils.WordUtil;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.XDDFNoFillProperties;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDLbls;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.STDispBlanksAs;
import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 文件导出
 *
 * @author liulindong
 * @version 2022/7/3 10:41
 */
@Service
public class WordChartService {


    /**
     * 导出普通的表格
     *
     * @param response 响应体
     */
    public void wordExport(HttpServletResponse response) {
        String contentType = "application/msword;charset=UTF-8";
        String fileName = "测试word模板";

        try (XWPFDocument document = new XWPFDocument()) {
            fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1) + ".docx";
            // 获取输出流
            ServletOutputStream outputStream = response.getOutputStream();
            // 创建标题
            WordUtil.createGeneralTitle(document, "好想。。。。。");
            // 创建表格
            XWPFTable table = document.createTable(2, 2);
            // 设置表格的宽度
            table.setWidthType(TableWidthType.PCT);
            table.setWidth("100%");
            // 表格居中
            table.setTableAlignment(TableRowAlign.CENTER);
            // 第0行第0列单元格
            XWPFTableCell cell0_0 = table.getRow(0).getCell(0);
            cell0_0.setText("赵舒婷");
            XWPFTableCell cell0_1 = table.getRow(0).getCell(1);
            cell0_1.setText("liulindong");
            XWPFTableCell cell1_0 = table.getRow(1).getCell(0);
            cell1_0.setText("haahhahha");
            XWPFTableCell cell1_1 = table.getRow(1).getCell(1);
            cell1_1.setText("就少了打开福建烤老鼠地方");

            // 单元格内容居中
            WordUtil.cellContentCenter(table);
            // 页边距
            WordUtil.setPageDistance(document);
            // 纵向合并单元格
            WordUtil.mergeCellsHorizontal(table, 0, 0, 1);
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            document.write(outputStream);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 导出word附带柱状图(柱状图+折线图)
     *
     * @param response 响应体
     */
    public void wordExportWithBarAndLine(HttpServletResponse response) {
        String contentType = "application/msword;charset=UTF-8";
        String fileName = "测试word模板.docx";

        try (XWPFDocument document = new XWPFDocument()) {
            ServletOutputStream outputStream = response.getOutputStream();
            // 柱状图数据
            String[] categories = new String[]{"课程目标1", "课程目标2", "课程目标3", "课程目标4", "课程目标5"};
            Double[] valuesA = new Double[]{10d, 20d, 30d, 20d, 30d};

            // create the chart
            XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
            // 去除圆角
            chart.getCTChartSpace().addNewRoundedCorners().setVal(false);

            // x轴数据
            XDDFCategoryDataSource categoriesData = XDDFDataSourcesFactory.fromArray(categories);
            // y轴数据
            XDDFNumericalDataSource<Double> valuesDataA = XDDFDataSourcesFactory.fromArray(valuesA);

            // 创建x轴体
            XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
            // 创建y轴体
            XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
            leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
            leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
            leftAxis.setMaximum(100);

            // 创建数据，BAR柱状图类型，将x轴，y轴放进去
            XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
            // 设置柱状图方向为竖向
            ((XDDFBarChartData) data).setBarDirection(BarDirection.COL);

            // 颜色变化
            data.setVaryColors(false);
            // 填充x轴，y轴数据
            XDDFChartData.Series series = data.addSeries(categoriesData, valuesDataA);
            // 数据说明
            series.setTitle("aaaaaa", null);

            // 数据说明的位置
            XDDFChartLegend legend = chart.getOrAddLegend();
            legend.setPosition(LegendPosition.BOTTOM);

            // 绘画图表
            chart.plot(data);


            // 折线图数据
            Double[] zhexianValue = new Double[]{5d, 5d, 5d, 5d, 5d};
            // 折线图y轴
            XDDFNumericalDataSource<Double> zhexianDataSource = XDDFDataSourcesFactory.fromArray(zhexianValue);
            // 创建折线图数据
            XDDFChartData zhexianData = chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis);
            XDDFChartData.Series zhexianSeries = zhexianData.addSeries(categoriesData, zhexianDataSource);
            zhexianSeries.setTitle("折线图", null);
            // 绘制折线图
            chart.plot(zhexianData);

            // 网格线
            chart.getCTChart().getPlotArea().getValAxList().get(0).addNewMinorGridlines();
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            document.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 读取模板文件，打印文件信息
     *
     * @param response http响应
     */
    public void wordHistogramByCopyTemplate(HttpServletResponse response) {
        String fileName = "test.doc";
        // 模板文件目录
        File template = new File("src/main/resources/wordTemplate/pieTemplate.docx");
        // 获取输出流
        ServletOutputStream outputStream = null;
        try (FileInputStream inputStream = new FileInputStream(template)) {
            outputStream = response.getOutputStream();
            response.setContentType("application/msword;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
            XWPFDocument document = new XWPFDocument(inputStream);
            System.out.println(document.getCharts().get(0).getCTChart());
            document.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 图表边框颜色设置为橙色
//            newChart.getCTChartSpace().addNewSpPr().addNewLn().addNewSolidFill().addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_2);
    }


    /**
     * 读取模板，生成目录
     *
     * @param response http响应
     */
    public void readTemplateCreateTOC(HttpServletResponse response) {
        String fileName = "test.docx";
        // 模板文件目录
        File template = new File("src/main/resources/wordTemplate/testCOT.docx");
        // 获取输出流
        ServletOutputStream outputStream = null;
        try (FileInputStream inputStream = new FileInputStream(template)) {
            // 获取word模板
            XWPFDocument templateDoc = new XWPFDocument(inputStream);
            System.out.println(templateDoc.getDocument());
            // 创建一级标题样式
            String firstCustomStyle = WordUtil.createHeadingStyle5_0_0(templateDoc, 1, 45, "000000", "宋体");
            // 创建二级标题样式
            String secondCustomStyle = WordUtil.createHeadingStyle5_0_0(templateDoc, 2, 35, "000000", "宋体");
            // 创建一级标题
            WordUtil.createTitleWithBookmark(templateDoc, "一级标题", firstCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "一级标题", firstCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            WordUtil.createTitleWithBookmark(templateDoc, "二级标题", secondCustomStyle);
            // 强制更新域
            templateDoc.enforceUpdateFields();
            outputStream = response.getOutputStream();
            response.setContentType("application/msword;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
            templateDoc.write(outputStream);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * word导出图表（散点图）
     *
     * @param response http响应
     */
    public void wordHistogramByDraw(HttpServletResponse response) {
        String fileName = "test.docx";
        ServletOutputStream outputStream = null;
        try (XWPFDocument document = new XWPFDocument()) {
            outputStream = response.getOutputStream();
            // x轴数据
            String[] xAxisData = new String[200];
            // y轴数据
            Double[] yAxisData = new Double[200];
            // 折线图y轴数据
            Double[] lingYAxisData = new Double[200];

            for (int i = 0; i < 200; i++) {
                xAxisData[i] = "" + i;
                yAxisData[i] = (double) (i % 10);
                lingYAxisData[i] = 5d;
            }
            // x轴数据源
            XDDFCategoryDataSource xAxisDataSource = XDDFDataSourcesFactory.fromArray(xAxisData);
            // y轴数据源
            XDDFNumericalDataSource<Double> yAxisDataSource = XDDFDataSourcesFactory.fromArray(yAxisData);
            // 折线图y轴数据源
            XDDFNumericalDataSource<Double> lineYAxisDataSource = XDDFDataSourcesFactory.fromArray(lingYAxisData);
            // 创建图表
            XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);

            // 不让图表标题嵌入到图表中
            chart.setTitleOverlay(false);
            chart.setTitleText("我是图标标题");
            // 创建x轴轴体,位置-底部
            XDDFCategoryAxis xAxisBody = chart.createCategoryAxis(AxisPosition.BOTTOM);
            xAxisBody.setTitle("我是x轴标题");
            // 创建y轴轴体，位置-左侧
            XDDFValueAxis yAxisBody = chart.createValueAxis(AxisPosition.LEFT);
            yAxisBody.setTitle("我是y轴标题");
            // 创建散点图
            XDDFChartData chartData = chart.createData(ChartTypes.SCATTER, xAxisBody, yAxisBody);
            // 颜色不可变
            chartData.setVaryColors(false);
            // 添加散点图数据源
            XDDFScatterChartData.Series chartSeries = (XDDFScatterChartData.Series) chartData.addSeries(xAxisDataSource, yAxisDataSource);
            chartSeries.setTitle("散点图说明", null);

            XDDFNoFillProperties fill = new XDDFNoFillProperties();
            // 散点图设置
            chartSeries.setFillProperties(fill);
            // 平滑过渡，开启为曲线，关闭为直线
            chartSeries.setSmooth(false);
            chartSeries.setMarkerStyle(MarkerStyle.CIRCLE);
            // 去掉连接线
            CTScatterChart scatterChart = chart.getCTChart().getPlotArea().getScatterChartList().get(0);
            List<CTScatterSer> serList = scatterChart.getSerList();
            for (CTScatterSer sser : serList) {
                sser.getSpPr().addNewLn().addNewNoFill();
            }

            // 折线图数据
            XDDFChartData lineData = chart.createData(ChartTypes.LINE, xAxisBody, yAxisBody);
            XDDFLineChartData.Series lineSeries = (XDDFLineChartData.Series) lineData.addSeries(xAxisDataSource, lineYAxisDataSource);
            lineSeries.setTitle("折线图说明", null);
            // 折线图连接方式，普通的连接
            lineSeries.setMarkerStyle(MarkerStyle.NONE);
            chart.getOrAddLegend().setPosition(LegendPosition.BOTTOM);

            // 图表边框颜色设置为灰色
            chart.getCTChartSpace().addNewSpPr().addNewLn().addNewSolidFill().addNewSchemeClr().setVal(STSchemeColorVal.BG_2);
            // 边框直角
            chart.getCTChartSpace().addNewRoundedCorners().setVal(false);
            // 添加网格, 要在绘制图表之前添加此代码，否则会报错
//            chart.getCTChart().getPlotArea().getValAxList().get(0).addNewMinorGridlines();
            // 绘制散点图
            chart.plot(chartData);
            // 绘制折线图
            chart.plot(lineData);
            response.setContentType("application/msword;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
            document.write(outputStream);
            outputStream.flush();
            // 输出图表格式,可以根据这个方法创建模板，然后调试格式
            System.out.println(chart.getCTChart());
        } catch (IOException | InvalidFormatException e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 生成课程评价报告（OBE）
     *
     * @param response http响应
     */
    public void exportCourseReport(HttpServletResponse response) {
        String contentType = "application/msword;charset=UTF-8";
        String fileName = "测试word模板";

        try (XWPFDocument document = new XWPFDocument()) {
            fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1) + ".docx";
            // 获取输出流
            ServletOutputStream outputStream = response.getOutputStream();
            // 创建标题
            WordUtil.createGeneralTitle(document, "《C程序程序设计》课程评价报告");
            // 第一部分标题
            WordUtil.createParagraphTitle(document, "一、评价方法");
            // 第一部分内容
            XWPFParagraph fistParagraph = document.createParagraph();
            WordUtil.partOne(fistParagraph, "《C语言程序设计》", Arrays.asList("1.2", "1.3", "1.4"), Arrays.asList("作业", "考试"));
            // 第一部分表格
            WordUtil.partOneTableOne(document, Arrays.asList("毕业要求指标点", "课程目标", "评价内容"));
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            document.write(outputStream);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public List<TableContent> requirementReady() {
        // 二级部分
        List<TableContent> seconds = new ArrayList<>();
        List<TableContent> seconds2 = new ArrayList<>();
        TableContent secondTableContent = new TableContent();
        TableContent secondTableContent2 = new TableContent();
        TableContent secondTableContent3 = new TableContent();
        TableContent secondTableContent4 = new TableContent();
        secondTableContent.setContent("课程目标1： 掌握数据库系统的基本概念、基本原理，了解数据库技术的最新发展动");
        secondTableContent2.setContent("课程目标 2：掌握关系数据库的基本概念、SQL语言编程和关系数据理论");
        secondTableContent3.setContent("课程目标 3：具备运行与维护数据库系统的技能");
        secondTableContent4.setContent("课程目标 4：掌握各种数据模型的特点、建模思想、规范化的设计理论和方法");
        seconds.add(secondTableContent);
        seconds.add(secondTableContent2);
        seconds2.add(secondTableContent3);
        seconds2.add(secondTableContent4);
        // 一级部分
        List<TableContent> first = new ArrayList<>();
        TableContent firstTableContent = new TableContent();
        TableContent firstTableContent2 = new TableContent();
        firstTableContent.setContent("1.2掌握解决复杂软件工程问题所必需的计算科学基础知识。");
        firstTableContent.setTableContents(seconds);
        firstTableContent2.setContent("2.2能够针对软件工程问题或软件系统建立合适的模型，清晰地表达和描述复杂软件工程问题。");
        firstTableContent2.setTableContents(seconds2);
        first.add(firstTableContent);
        first.add(firstTableContent2);

        return first;
    }


    /**
     * 测试生成目录(生成在最顶端)
     *
     * @param response http响应
     */
    public void wordCatalogue(HttpServletResponse response) {
        String contentType = "application/msword;charset=UTF-8";
        String fileName = "测试word生成目录";

        try (XWPFDocument document = new XWPFDocument()) {
            fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1) + ".docx";
            // 获取输出流
            ServletOutputStream outputStream = response.getOutputStream();
            // 生成页码
            WordUtil.createPageNum(document);
            // 创建一级标题样式
            String firstCustomStyle = WordUtil.createHeadingStyle5_0_0(document, 1, 45, "000000", "宋体");
            // 创建二级标题样式
            String secondCustomStyle = WordUtil.createHeadingStyle5_0_0(document, 2, 35, "000000", "宋体");
            // 创建一级标题
            WordUtil.createTitleWithBookmark(document, "一级标题", firstCustomStyle);
            WordUtil.createTitleWithBookmark(document, "一级标题", firstCustomStyle);
            // 创建目录
//            WordUtil.createTOC(document);
            // 更新目录
            document.createTOC();
//            document.enforceUpdateFields();
            OPCPackage aPackage = document.getPackage();
            XWPFDocument tempDocument = new XWPFDocument(aPackage);
            tempDocument.enforceUpdateFields();
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            tempDocument.write(outputStream);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * word生成圆环图
     *
     * @param response http响应
     */
    public void createDoughnutChart(HttpServletResponse response) {
        String contentType = "application/msword;charset=UTF-8";
        String fileName = "测试word模板.docx";

        try (XWPFDocument document = new XWPFDocument()) {
            ServletOutputStream outputStream = response.getOutputStream();
            // 柱状图数据
            String[] categories = new String[]{"课程目标1", "课程目标2", "课程目标3", "课程目标4", "课程目标5"};
            Double[] valuesA = new Double[]{10d, 20d, 30d, 20d, 30d};

            // 创建图表
            XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);

            // 数据说明的位置
//            XDDFChartLegend legend = chart.getOrAddLegend();
//            legend.setPosition(LegendPosition.TOP);


            // x轴数据
            XDDFCategoryDataSource categoriesData = XDDFDataSourcesFactory.fromArray(categories, null);
            // y轴数据
            XDDFNumericalDataSource<Double> valuesDataA = XDDFDataSourcesFactory.fromArray(valuesA, null);

            // 图例生成在底部
//            XDDFChartLegend orAddLegend = chart.getOrAddLegend();
//            orAddLegend.setPosition(LegendPosition.BOTTOM);

            XDDFDoughnutChartData data = (XDDFDoughnutChartData) chart.createData(ChartTypes.DOUGHNUT, null, null);
//            data.setVaryColors(true);

            // 填充x轴，y轴数据
            XDDFDoughnutChartData.Series series = (XDDFDoughnutChartData.Series) data.addSeries(categoriesData, valuesDataA);
            // 数据说明
            series.setTitle("aaaaaa", null);

            // 内部圆环大小，50%
            chart.getCTChart().getPlotArea().getDoughnutChartArray(0).addNewHoleSize().setVal(50);
            // 绘画图表
            chart.plot(data);


            // 网格线
//            chart.getCTChart().getPlotArea().getValAxList().get(0).addNewMinorGridlines();
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            document.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    /**
     * 测试word表格内单元格换行
     * @param response http响应
     */
    public void testTableCellNextLine(HttpServletResponse response) {
        String contentType = "application/octet-stream;charset=UTF-8";
        String fileName = "测试word模板";

        try (XWPFDocument document = new XWPFDocument()) {
            fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1) + ".docx";
            ServletOutputStream outputStream = response.getOutputStream();
            XWPFTable table = document.createTable();
            XWPFTableRow row = table.getRow(0);
            XWPFTableCell cell = row.getCell(0);
            cell.setWidth("5000");
            cell.setText("仅仅仅仅军军");
            cell.addParagraph().createRun().setText("草");
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            document.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void exportPicture(HttpServletResponse response) {
        String contentType = "application/octet-stream;charset=UTF-8";
        String fileName = "测试word模板";

        try (XWPFDocument document = new XWPFDocument()) {
            fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1) + ".docx";
            ServletOutputStream outputStream = response.getOutputStream();
            byte[] bytes = PictureUtils.imageToByteArrayOnline("https://staticfile.eec-cn.com/ff80808168237aa701683abc0f685341/richtext/image/20200219/1582094211591015454.png");
            String pictureId = document.addPictureData(bytes, XWPFDocument.PICTURE_TYPE_PNG);
            PictureUtils.createPicture(document, pictureId, document.getNextPicNameNumber(XWPFDocument.PICTURE_TYPE_PNG), 200, 100);
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            document.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public void exportRichTextWord(HttpServletResponse response) {

        String contentType = "application/octet-stream;charset=UTF-8";
        String fileName = "测试导出富文本";

        try (XWPFDocument document = new XWPFDocument()) {
            ServletOutputStream outputStream = response.getOutputStream();
            fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1) + ".docx";
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            Word07Writer writer = new Word07Writer();
            writer.addText(new Font("宋体", Font.PLAIN, 22), "<html><body><h1>66666</h1></body></html>");

            writer.flush(outputStream);

            outputStream.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }




    public void exportByPOISystem(HttpServletResponse response) {

        String contentType = "application/msword;charset=UTF-8";
        String fileName = "智能语音识别";

        try {
            ServletOutputStream outputStream = response.getOutputStream();
            fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1) + ".doc";
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            // 生成内容
            String html = "<html>\n <head></head> \n <body> \n  <h1 style=\"text-align:center;\" id=\"JFTX-1\">《JavaEE企业开发框架（SSM）》</h1> \n  <h1 style=\"text-align:center;\" id=\"7HOR-1\">—课程大纲</h1> \n  <h2 id=\"O93R-2\">一、课程基本信息</h2> \n  <p>1.&nbsp;课程编号：</p> \n  <p>2.&nbsp;课程体系/类别：专业课</p> \n  <p>3.&nbsp;课程性质：必修</p> \n  <p>4.&nbsp;学时/学分：64/3</p> \n  <p>5.&nbsp;先修课程：JavaWeb开发技术</p> \n  <p>6.&nbsp;适用专业：计算机软件、网络工程等专业</p> \n  <h2 id=\"WTZY-2\">二、课程教学目标</h2> \n  <p class=\"ck-textindent\">本课程是面向JavaEE企业级应用开发的平台技术，是在学习Java Web技术基础课程后，面向企业实际应用的综合性课程。JavaEE开发技术以其开放性、灵活性、安全性、跨平台和技术成熟度，在企业级业务开发领域中占据了较大的市场份额，同时以其优秀的体系架构及开发规范，为大型企业机构创建分布式、安全的、具有高反应性的网络应用提供技术支持。</p> \n  <p class=\"ck-textindent\">本课程以JavaEE开发技术的三个主流框架：SpringMVC、Spring、MyBatis为核心，分别对三个框架的起源背景、发展优势、系统架构、运行原理、框架功能进行全面细致的介绍，并配以大量课程案例和企业真实项目实验，从理论到实践对学生进行综合能力的培养，为后续学生进行中大型企业应用开发奠定坚实基础。本课程目标具体如下：</p> \n  <ol> \n   <li>理解框架及Spring IOC容器、Bean生命周期、AOP等理念的核心思想；</li> \n   <li>掌握Spring框架的Bean依赖配置、AOP实现、数据库操作、事务管理、线程池、任务调度等操作；</li> \n   <li>理解SpringMVC工作原理；</li> \n   <li>掌握SpringMVC框架的常用注解、数据转换和格式化、标签库、国际化、文件上传下载、拦截器、JSON数据交互和RESTful支持；</li> \n   <li>理解MyBatis工作原理及发展史；</li> \n   <li>掌握MyBatis框架的核心配置、关联映射、延迟加载、缓存、动态SQL等操作；</li> \n   <li>掌握Spring与SpringMVC和MyBatis的整合开发；</li> \n   <li>具备查阅相关学习资源及自我学习的能力；</li> \n   <li>具备熟练使用集成开发工具（如Eclipse等）的能力。</li> \n  </ol> \n  <h2 id=\"K9RA-2\">三、课程教学内容和要求</h2> \n  <figure class=\"table\" style=\"width:100.0%;\"> \n   <table> \n    <tbody> \n     <tr> \n      <td><p style=\"text-align:center;\"><strong>序号</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>知识单元（章节）</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>知识点</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>要求</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>推荐学时</strong></p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"3\"><p style=\"text-align:center;\">1</p></td> \n      <td rowspan=\"3\">第1章 Spring入门</td> \n      <td>1.1&nbsp;框架简介</td> \n      <td><p style=\"text-align:center;\">了解</p></td> \n      <td rowspan=\"3\"><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td>1.2 Spring概述</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n     </tr> \n     <tr> \n      <td>1.3&nbsp;第一个Spring程序</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"6\"><p style=\"text-align:center;\">2</p></td> \n      <td rowspan=\"6\">第2章 Spring IOC与Bean</td> \n      <td>2.1 IOC&amp;DI概念理解</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n      <td rowspan=\"6\"><p style=\"text-align:center;\">4</p></td> \n     </tr> \n     <tr> \n      <td>2.2 Spring IOC容器</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n     </tr> \n     <tr> \n      <td>2.3 Bean生命周期管理</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>2.4 Bean的配置</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>2.5 Bean的依赖注入</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>2.6 Bean之间的关系</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">3</p></td> \n      <td rowspan=\"4\">第3章 Spring AOP</td> \n      <td>3.1 AOP编程思想</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">4</p></td> \n     </tr> \n     <tr> \n      <td>3.2 Spring AOP概述</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n     </tr> \n     <tr> \n      <td>3.3 XML配置方式实现AOP</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>3.4 AspectJ注解方式实现AOP</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">4</p></td> \n      <td rowspan=\"4\">第4章 Spring数据库操作</td> \n      <td>4.1 Spring数据库管理</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">4</p></td> \n     </tr> \n     <tr> \n      <td>4.2 Spring数据库操作</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>4.3 Spring事务管理</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n     </tr> \n     <tr> \n      <td>4.4 Spring事务实现</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">5</p></td> \n      <td rowspan=\"4\">第5章 Spring线程池和任务调度</td> \n      <td>5.1&nbsp;线程池</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">3</p></td> \n     </tr> \n     <tr> \n      <td>5.2 Spring线程池</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>5.3&nbsp;任务调度</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n     </tr> \n     <tr> \n      <td>5.4 Spring任务调度框架</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">6</p></td> \n      <td rowspan=\"4\">第6章 SpringMVC概述</td> \n      <td>6.1 SpringMVC特征</td> \n      <td><p style=\"text-align:center;\">了解</p></td> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td>6.2 Maven Web项目结构</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>6.3 SpringMVC入门程序</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>6.4 SpringMVC工作原理</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">7</p></td> \n      <td rowspan=\"4\">第7章 SpringMVC常用的注解</td> \n      <td>7.1 Controller注解</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">3</p></td> \n     </tr> \n     <tr> \n      <td>7.2 RequestMapping注解</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>7.3&nbsp;请求处理方法</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>7.4&nbsp;参数绑定注解</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">8</p></td> \n      <td rowspan=\"4\">第8章&nbsp;数据转换和数据格式化</td> \n      <td>8.1&nbsp;数据绑定</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">3</p></td> \n     </tr> \n     <tr> \n      <td>8.2&nbsp;数据类型转换</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>8.3&nbsp;数据格式化</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>8.4 Annotation数据格式化</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">9</p></td> \n      <td rowspan=\"2\">第9章 SpringMVC标签库</td> \n      <td>9.1 SpringMVC标签库</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">3</p></td> \n     </tr> \n     <tr> \n      <td>9.2&nbsp;数据校验</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">10</p></td> \n      <td rowspan=\"2\">第10章 SpringMVC国际化</td> \n      <td>10.1&nbsp;国际化</td> \n      <td><p style=\"text-align:center;\">理解</p></td> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td>10.2&nbsp;语言区域解析器</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"3\"><p style=\"text-align:center;\">11</p></td> \n      <td rowspan=\"3\">第11章 SpringMVC文件上传下载及拦截器</td> \n      <td>11.1&nbsp;文件上传</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"3\"><p style=\"text-align:center;\">3</p></td> \n     </tr> \n     <tr> \n      <td>11.2&nbsp;文件下载</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>11.3&nbsp;拦截器</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">12</p></td> \n      <td rowspan=\"2\">第12章 JSON数据交互和RESTful支持</td> \n      <td>12.1 JSON数据交互</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td>12.2 RESTful支持</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"3\"><p style=\"text-align:center;\">13</p></td> \n      <td rowspan=\"3\">第13章 MyBatis概述</td> \n      <td>13.1 MyBatis发展史</td> \n      <td><p style=\"text-align:center;\">了解</p></td> \n      <td rowspan=\"3\"><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td>13.2 MyBatis的下载和使用</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>13.3 MyBatis操作及原理</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">14</p></td> \n      <td rowspan=\"2\">第14章 MyBatis核心配置</td> \n      <td>14.1 MyBatis配置文件</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td>14.2 MyBatis映射文件</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"3\"><p style=\"text-align:center;\">15</p></td> \n      <td rowspan=\"3\">第15章 MyBatis关联映射</td> \n      <td>15.1 MyBatis关联映射</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"3\"><p style=\"text-align:center;\">3</p></td> \n     </tr> \n     <tr> \n      <td>15.2 MyBatis延迟加载</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>15.3 MyBatis缓存</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td><p style=\"text-align:center;\">16</p></td> \n      <td>第16章 MyBatis动态SQL</td> \n      <td>16.1 MyBatis动态SQL</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">17</p></td> \n      <td rowspan=\"4\">第17章 MyBatis与Spring整合</td> \n      <td>17.1&nbsp;整合环境搭建</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"4\"><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td>17.2&nbsp;编写配置文件</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>17.3&nbsp;整合开发方式</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td>17.4&nbsp;事务的应用</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n     <tr> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">18</p></td> \n      <td rowspan=\"2\">第18章 SSM框架整合</td> \n      <td>18.1&nbsp;整合步骤</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n      <td rowspan=\"2\"><p style=\"text-align:center;\">2</p></td> \n     </tr> \n     <tr> \n      <td>18.2&nbsp;整合测试</td> \n      <td><p style=\"text-align:center;\">掌握</p></td> \n     </tr> \n    </tbody> \n   </table> \n  </figure> \n  <h2 id=\"7WT0-2\">四、课程教学方法</h2> \n  <p>（一）课堂讲授（48学时）</p> \n  <p>引入问题/场景/案例，分析解决思路，讲述案例相关知识点定义及用法、原理与方法；总结和补充，提出新任务，扩展知识点学习深度，启发学生自我解决问题，在实例中体现程序的编写过程、代码规范性，在教学过程中展示解决问题和编写程序的过程。</p> \n  <p>（二）作业和实验（16学时）</p> \n  <p>1.根据知识点设计作业题目：每章针对本章知识要点留2道左右的课后编程练习题。</p> \n  <p>2.自主学习扩展知识：根据已学的知识，通过举一反三，自主学习相关理论和技术。这部分内容针对学习能力强，学有余力的学生，不做统一要求。</p> \n  <p>3.其中实验课时安排及要求如下：</p> \n  <p>实验项目及要求：</p> \n  <figure class=\"table\" style=\"width:100.0%;\"> \n   <table> \n    <tbody> \n     <tr> \n      <td><p style=\"text-align:center;\"><strong>序号</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>实验名称</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>目的与要求</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>实验学时</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>主要</strong></p><p style=\"text-align:center;\"><strong>仪器设备</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>实验类型</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>性质</strong></p></td> \n     </tr> \n     <tr> \n      <td><p style=\"text-align:center;\">1</p></td> \n      <td>实验1：利用Spring IOC容器实现的个人简易记帐系统</td> \n      <td><p>理解什么是IOC与DI；</p><p>了解Spring IOC&nbsp;的注入值类与Bean作用域；</p><p>掌握自动装配的原理与用法；</p><p>掌握Spring IOC容器Bean实例化的几种场景。</p></td> \n      <td><p style=\"text-align:center;\">4</p></td> \n      <td>个人PC&nbsp;</td> \n      <td><p style=\"text-align:center;\">验证</p></td> \n      <td><p style=\"text-align:center;\">必做</p></td> \n     </tr> \n     <tr> \n      <td><p style=\"text-align:center;\">2</p></td> \n      <td>实验2：SpringMVC注解在CRM客户关系管理系统中的实现</td> \n      <td><p>掌握如何搭建Spring MVC Maven项目工程框架；</p><p>了解Spring MVC常用注解作用及适用场景；</p><p>熟练使用Spring MVC注解；</p><p>掌握Spring MVC注解在JAVA开发中的应际应用。</p></td> \n      <td><p style=\"text-align:center;\">4</p></td> \n      <td>个人PC&nbsp;</td> \n      <td><p style=\"text-align:center;\">验证</p></td> \n      <td><p style=\"text-align:center;\">必做</p></td> \n     </tr> \n     <tr> \n      <td><p style=\"text-align:center;\">3</p></td> \n      <td>实验3：MyBatis关联映射在“问道”知识分享垂直问答社区中的实战应用</td> \n      <td><p>了解MyBatis的原理；</p><p>掌握MyBatis的基础配置；</p><p>掌握MyBatis的一对一配置；</p><p>掌握MyBatis的一对多配置；</p><p>掌握MyBatis的多对多配置。</p></td> \n      <td><p style=\"text-align:center;\">4</p></td> \n      <td>个人PC&nbsp;</td> \n      <td><p style=\"text-align:center;\">验证</p></td> \n      <td><p style=\"text-align:center;\">必做</p></td> \n     </tr> \n     <tr> \n      <td><p style=\"text-align:center;\">4</p></td> \n      <td>实验4：利用MyBatis缓存提升“问道”知识分享垂直问答社区的数据访问性能</td> \n      <td><p>了解MyBatis一级缓存原理</p><p>掌握MyBatis一级缓存配置</p><p>了解MyBatis二级缓存原理</p><p>掌握MyBatis二级缓存配置</p><p>掌握MyBatis缓存在项目开发中实际应用</p></td> \n      <td><p style=\"text-align:center;\">4</p></td> \n      <td>个人PC&nbsp;</td> \n      <td><p style=\"text-align:center;\">验证</p></td> \n      <td><p style=\"text-align:center;\">必做</p></td> \n     </tr> \n    </tbody> \n   </table> \n  </figure> \n  <h2 id=\"QF88-2\">五、课程考核</h2> \n  <figure class=\"table\" style=\"width:100.0%;\"> \n   <table> \n    <tbody> \n     <tr> \n      <td><p style=\"text-align:center;\"><strong>考核环节</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>评分标准</strong></p></td> \n      <td><p style=\"text-align:center;\"><strong>建议比重</strong></p></td> \n     </tr> \n     <tr> \n      <td style=\"vertical-align:top;\">平时成绩（含课堂点名、课堂练习、课堂作业）</td> \n      <td style=\"vertical-align:top;\">出勤率，课堂讨论积极，踊跃回答问题</td> \n      <td style=\"vertical-align:top;\">10%</td> \n     </tr> \n     <tr> \n      <td style=\"vertical-align:top;\">实验成绩（含实验操作、实验报告）</td> \n      <td style=\"vertical-align:top;\">考察学生编码动手能力和文档编写能力</td> \n      <td style=\"vertical-align:top;\">30%</td> \n     </tr> \n     <tr> \n      <td style=\"vertical-align:top;\">结课考试</td> \n      <td style=\"vertical-align:top;\">概念清楚，能综合运用所学知识分析问题、解决问题</td> \n      <td style=\"vertical-align:top;\">60%</td> \n     </tr> \n    </tbody> \n   </table> \n  </figure> \n  <h2 id=\"Z4I9-2\">六、本课程与其它课程的联系与分工</h2> \n  <p>先修课：JavaEE企业级开发</p> \n  <p>后续课程：企业开发实战，毕业设计</p> \n  <h2 id=\"X8S5-2\">七、建议教材及教学参考书</h2> \n  <p>教材选用理论体系完整且难度适中，有一定的应用技术实例，提供大量参考书和学习资源以满足不同层次学生学习需求。</p> \n  <p><strong>建议教材</strong></p> \n  <p>[1] SSM轻量级框架应用开发教程，张桓，刘仲会，丁明浩 著，人民邮电出版社，2020.</p> \n  <p><strong>教学参考书</strong></p> \n  <p>[1]&nbsp;互联网轻量级SSM框架解密：Spring、Spring MVC、MyBatis源码深度剖析，李艳鹏 等 著，电子工业出版社，2019.</p> \n  <p>[2] Java EE互联网轻量级框架整合开发 SSM框架（Spring MVC+Spring+MyBatis）和Redis实现，杨开振，周吉文，梁华辉，谭茂华 著，电子工业出版社，2017</p> \n  <p>&nbsp;</p>  \n </body>\n</html>";

            // 替换样式()
            byte[] b = html.getBytes(StandardCharsets.UTF_8);
            // 将字节数组包装到流中
            ByteArrayInputStream bais = new ByteArrayInputStream(b);
            POIFSFileSystem poifs = new POIFSFileSystem();
            DirectoryEntry directory = poifs.getRoot();
            directory.createDocument("WordDocument", bais);
            poifs.writeFilesystem(outputStream);
            outputStream.close();
            bais.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }




    public void exportByHutool(HttpServletResponse response) {

        String contentType = "application/ms;charset=UTF-8";
        String fileName = "智能语音识别";

        try {
            File file = new File("D://finalTest.docx");

            XWPFDocument document = new XWPFDocument(new FileInputStream(file));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public void exportByAspose(HttpServletResponse response) {
        try {
            String contentType = "application/octet-stream;charset=UTF-8";
            // 三级标题
            String heading1 = AsposeWordUtil.createHeading("我是一级标题", 1);
            String heading2 = AsposeWordUtil.createHeading("我是二级标题", 2);
            String heading3 = AsposeWordUtil.createHeading("我是三级标题", 3);
            // 主内容
            String content = AsposeWordUtil.createContent("<figure class=\"image image_resized\" style=\"width:328px;\"><img src=\"https://tecs-tev-static.obs.cn-north-1.myhuaweicloud.com:443/88ac5ee49fc84caa90ac3e14d8bfe237%2Frichtext%2Fimage%2F20230327%2Fa34582bad4e245cfae1d115ef89e7fa0.gif\"></figure>");
            // 最后主内容
            String finalContent = heading1 + heading2 + heading3 + content;
            // 生成style标签
            String styleLabel = AsposeWordUtil.createStyleLabel();

            com.aspose.words.Document document = new com.aspose.words.Document();
            DocumentBuilder builder = new DocumentBuilder(document);
            String fileName = new String("fileName".getBytes(), StandardCharsets.ISO_8859_1) + ".docx";
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            finalContent  = finalContent.replaceAll("(<figure.*?style=)(\".*?\")(.*?>)(\\s*<\\s*img)(\\s+([^>]*?)(\\s*/?>\\s*</figure>))", "$1$2$3$4 style=$2 $5");
            // 将html插入
            builder.insertHtml(AsposeWordUtil.getHtml(styleLabel, finalContent));
            ServletOutputStream outputStream = response.getOutputStream();
//            // 页眉页脚
//            AsposeWordUtil.addHeaderAndFooter(document);
//            // 创建并更新目录
//            AsposeWordUtil.createAndUpdateTOC(document, builder);
            document.save(outputStream, SaveFormat.DOCX);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }




    public void exportPie(HttpServletRequest request, HttpServletResponse response) {
        String contentType = "application/msword;charset=UTF-8";
        String fileName = "测试word模板.docx";

        // 柱状图数据
        String[] categories = {"第一季度", "第二季度", "第三季度", "第四季度"};
        Double[] valuesA = {1d, 2d, null, 3d};

        XWPFDocument document = new XWPFDocument();
        // 创建图表
        XWPFChart chart = null;
        try {
            chart = document.createChart(14 * Units.EMU_PER_CENTIMETER, 9 * Units.EMU_PER_CENTIMETER);
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        chart.setTitleText("学分占比");
        // 标题不覆盖图表
        chart.setTitleOverlay(false);

        // 图例的位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.BOTTOM);

        // x轴数据
        XDDFCategoryDataSource categoriesData = XDDFDataSourcesFactory.fromArray(categories);
        // y轴数据
        XDDFNumericalDataSource<Double> valuesDataA = XDDFDataSourcesFactory.fromArray(valuesA);

        XDDFPieChartData chartData = (XDDFPieChartData) chart.createData(ChartTypes.PIE, null, null);
        chartData.setVaryColors(true);



        // 填充数据
        chartData.addSeries(categoriesData, valuesDataA);
//        System.out.println(chart.getCTChart());
//
//        CTPieChart pieChart = chart.getCTChart().getPlotArea().getPieChartList().get(0);
//        CTPieSer ser = pieChart.addNewSer();
//        ser.addNewIdx().setVal(0);
//        ser.addNewOrder().setVal(0);
//        CTSerTx tx = ser.addNewTx();
//        CTStrRef ref = tx.addNewStrRef();
//        CTStrData strCache = ref.addNewStrCache();
//        strCache.addNewPtCount().setVal(1);
//        CTStrVal pt = strCache.addNewPt();
//        pt.setIdx(0);
//        pt.setV("学分占比");
//
//        CTAxDataSource cat = ser.addNewCat();
//        CTStrRef strRef = cat.addNewStrRef();
//        CTStrData strCacheData = strRef.addNewStrCache();
//        strCacheData.addNewPtCount().setVal(4);
//        for (int i = 0; i < 4; i++) {
//            CTStrVal currentPt = strCacheData.addNewPt();
//            currentPt.setIdx(i);
//            currentPt.setV("第" + i + "季度");
//        }

//
//        CTNumDataSource value = ser.addNewVal();
//        CTNumRef numRef = value.addNewNumRef();
//        CTNumData numCache = numRef.addNewNumCache();
//        numCache.setFormatCode("General");
//        numCache.addNewPtCount().setVal(4);
//        for (int i = 0; i < 4; i++) {
//            if (i == 0) {
//                continue;
//            }
//            CTNumVal currentPt = numCache.addNewPt();
//            currentPt.setIdx(i);
//            currentPt.setV(String.valueOf(i));
//        }
//
//
//        System.out.println(ser);
        // 饼图上显示具体数值
        CTDLbls ctdLbls = chart.getCTChart().getPlotArea().getPieChartArray(0).addNewDLbls();
        ctdLbls.addNewShowLegendKey().setVal(false);
        ctdLbls.addNewShowVal().setVal(true);
        ctdLbls.addNewShowPercent().setVal(false);
        ctdLbls.addNewShowCatName().setVal(false);
        ctdLbls.addNewShowSerName().setVal(false);
        ctdLbls.addNewLeaderLines();
        // 图表边框颜色设置为灰色
        chart.getCTChartSpace().addNewSpPr().addNewLn().addNewSolidFill().addNewSchemeClr().setVal(STSchemeColorVal.BG_2);
        // 边框直角
        chart.getCTChartSpace().addNewRoundedCorners().setVal(false);
//        chart.setPlotOnlyVisibleCells(true);
        chart.getCTChart().addNewDispBlanksAs().setVal(STDispBlanksAs.GAP);
        // 绘画图表
        chart.plot(chartData);
        System.out.println(chart.getCTChartSpace());
        try {
            WordUtil.drawReportExport(request, response, document, "test");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
